package com.keyue.common.exception.handler;


import com.keyue.common.constant.ServerResult;
import com.keyue.common.constant.ServerResultCode;
import com.keyue.common.exception.BusinessException;
import com.keyue.common.exception.EntityExistException;
import com.keyue.common.exception.EntityNotFoundException;
import com.keyue.common.utils.ThrowableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.util.Objects;

/**
 * @date 2018-11-23
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * @param exception
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseEntity<Object> handleServiceException(Exception exception) throws Exception {
        return new ResponseEntity(translateException(exception), HttpStatus.OK);
    }

    /**
     * @param exception
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<Object> handleException(Exception exception) throws Exception {
        return new ResponseEntity<Object>(translateException(exception), HttpStatus.OK);
    }


    /**
     * 处理所有接口数据验证异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ServerResult> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\.");
        String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        String msg = "不能为空";
        if (msg.equals(message)) {
            message = str[1] + ":" + message;
        }
        return buildResponseEntity(ServerResult.fail(message));
    }

    /**
     * 处理自定义异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BusinessException.class)
    public ResponseEntity<ServerResult> badRequestException(BusinessException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        return buildResponseEntity(ServerResult.fail(e.getErrorCode(), e.getMessage()));
    }

    /**
     * 处理 EntityExist
     */
    @ExceptionHandler(value = EntityExistException.class)
    public ResponseEntity<ServerResult> entityExistException(EntityExistException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        return buildResponseEntity(ServerResult.fail(e.getMessage()));
    }

    /**
     * 处理 EntityNotFound
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = EntityNotFoundException.class)
    public ResponseEntity<ServerResult> entityNotFoundException(EntityNotFoundException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        return buildResponseEntity(ServerResult.fail(HttpStatus.NOT_FOUND.value(), e.getMessage()));
    }

    /**
     * @param serverResult
     * @return
     */
    private ResponseEntity<ServerResult> buildResponseEntity(ServerResult serverResult) {
        return new ResponseEntity<>(serverResult, HttpStatus.valueOf(200));
    }

    /**
     * @param e
     * @return
     * @throws Exception
     */
    private Object translateException(Exception e) throws Exception {
        ServerResult serverResult = null;
        if (e instanceof NullPointerException) {
            serverResult = ServerResult.fail(ServerResultCode.NULL_POINT);
        } else if (e instanceof IllegalArgumentException) {
            serverResult = ServerResult.fail(ServerResultCode.FAIL);
        } else if (e instanceof MaxUploadSizeExceededException) {
            serverResult = ServerResult.fail(ServerResultCode.FIlE_UPLOAD_TOO_LARGE);
        } else if (e instanceof BusinessException) {
            serverResult = ServerResult.fail(((BusinessException) e).getErrorCode(), ((BusinessException) e).getErrorDesc());
        } else {
            serverResult = ServerResult.fail(ServerResultCode.FAIL);
            serverResult.setMessage(serverResult.getMessage() + "|,业务异常:" + e.getMessage());
        }

        log.error("业务异常", e);
        return serverResult;
    }
}
